﻿using ServiceStack.Redis;
using ServiceStack.Redis.Support;
using ServiceStack.Text;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RedisDemo
{
    class Program
    {
      
            static void Main(string[] args)
            {
                try
                {
                    //获取Redis操作接口  
                    IRedisClient Redis = RedisManager.GetClient();
                    //Hash表操作  
                    HashOperator operators = new HashOperator();

                    //移除某个缓存数据  
                    bool isTrue = Redis.Remove("additemtolist");

                    //将字符串列表添加到redis  
                    List<string> storeMembers = new List<string>() { "韩梅梅", "李雷", "露西" };
                    storeMembers.ForEach(x => Redis.AddItemToList("additemtolist", x));
                    //得到指定的key所对应的value集合  
                    Console.WriteLine("得到指定的key所对应的value集合：");
                    var members = Redis.GetAllItemsFromList("additemtolist");
                    members.ForEach(s => Console.WriteLine("additemtolist :" + s));
                    Console.WriteLine("");

                    // 获取指定索引位置数据  
                    Console.WriteLine("获取指定索引位置数据：");
                    var item = Redis.GetItemFromList("additemtolist", 2);
                    Console.WriteLine(item);

                    Console.WriteLine("");

                    //将数据存入Hash表中  
                    Console.WriteLine("Hash表数据存储:");
                    UserInfo userInfos = new UserInfo() { UserName = "李雷", Age = 45 };
                    var ser = new ObjectSerializer();    //位于namespace ServiceStack.Redis.Support;  
                    bool results = operators.Set<byte[]>("userInfosHash", "userInfos", ser.Serialize(userInfos));
                    byte[] infos = operators.Get<byte[]>("userInfosHash", "userInfos");
                    userInfos = ser.Deserialize(infos) as UserInfo;
                    Console.WriteLine("name=" + userInfos.UserName + "   age=" + userInfos.Age);

                    Console.WriteLine("");

                    //object序列化方式存储  
                    Console.WriteLine("object序列化方式存储:");
                    UserInfo uInfo = new UserInfo() { UserName = "张三", Age = 12 };
                    bool result = Redis.Set<byte[]>("uInfo", ser.Serialize(uInfo));
                    UserInfo userinfo2 = ser.Deserialize(Redis.Get<byte[]>("uInfo")) as UserInfo;
                    Console.WriteLine("name=" + userinfo2.UserName + "   age=" + userinfo2.Age);

                    Console.WriteLine("");

                    //存储值类型数据  
                    Console.WriteLine("存储值类型数据:");
                    Redis.Set<int>("my_age", 12);//或Redis.Set("my_age", 12);  
                    int age = Redis.Get<int>("my_age");
                    Console.WriteLine("age=" + age);

                    Console.WriteLine("");

                    //序列化列表数据  
                    Console.WriteLine("列表数据:");
                    List<UserInfo> userinfoList = new List<UserInfo> {
                new UserInfo{UserName="露西",Age=1,Id=1},
                new UserInfo{UserName="玛丽",Age=3,Id=2},
            };
                    Redis.Set<byte[]>("userinfolist_serialize", ser.Serialize(userinfoList));
                    List<UserInfo> userList = ser.Deserialize(Redis.Get<byte[]>("userinfolist_serialize")) as List<UserInfo>;
                    userList.ForEach(i =>
                    {
                        Console.WriteLine("name=" + i.UserName + "   age=" + i.Age);
                    });
                    //释放内存  
                    Redis.Dispose();
                    operators.Dispose();
                    Console.ReadKey();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message.ToString());
                    Console.WriteLine("Please open the redis-server.exe ");
                    Console.ReadKey();
                }
            }
        }
    [Serializable]
    public class UserInfo
    {
        public int Id;
        public string UserName;
        public int Age;
    }

    /// <summary>  
    /// RedisManager类主要是创建链接池管理对象的  
    /// </summary>  
    public class RedisManager
    {
        /// <summary>  
        /// redis配置文件信息  
        /// </summary>  
        private static string RedisPath = System.Configuration.ConfigurationSettings.AppSettings["RedisPath"];
        private static PooledRedisClientManager _prcm;

        /// <summary>  
        /// 静态构造方法，初始化链接池管理对象  
        /// </summary>  
        static RedisManager()
        {
            CreateManager();
        }

        /// <summary>  
        /// 创建链接池管理对象  
        /// </summary>  
        private static void CreateManager()
        {
            _prcm = CreateManager(new string[] { RedisPath }, new string[] { RedisPath });
        }


        private static PooledRedisClientManager CreateManager(string[] readWriteHosts, string[] readOnlyHosts)
        {
            //WriteServerList：可写的Redis链接地址。  
            //ReadServerList：可读的Redis链接地址。  
            //MaxWritePoolSize：最大写链接数。  
            //MaxReadPoolSize：最大读链接数。  
            //AutoStart：自动重启。  
            //LocalCacheTime：本地缓存到期时间，单位:秒。  
            //RecordeLog：是否记录日志,该设置仅用于排查redis运行时出现的问题,如redis工作正常,请关闭该项。  
            //RedisConfigInfo类是记录redis连接信息，此信息和配置文件中的RedisConfig相呼应  

            // 支持读写分离，均衡负载   
            return new PooledRedisClientManager(readWriteHosts, readOnlyHosts, new RedisClientManagerConfig
            {
                MaxWritePoolSize = 5, // “写”链接池链接数   
                MaxReadPoolSize = 5, // “读”链接池链接数   
                AutoStart = true,
            });
        }

        private static IEnumerable<string> SplitString(string strSource, string split)
        {
            return strSource.Split(split.ToArray());
        }

        /// <summary>  
        /// 客户端缓存操作对象  
        /// </summary>  
        public static IRedisClient GetClient()
        {
            if (_prcm == null)
            {
                CreateManager();
            }
            return _prcm.GetClient();
        }

    }


    /// <summary>  
    /// RedisOperatorBase类，是redis操作的基类，继承自IDisposable接口，主要用于释放内存  
    /// </summary>  
    public abstract class RedisOperatorBase : IDisposable
    {
        protected IRedisClient Redis { get; private set; }
        private bool _disposed = false;
        protected RedisOperatorBase()
        {
            Redis = RedisManager.GetClient();
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!this._disposed)
            {
                if (disposing)
                {
                    Redis.Dispose();
                    Redis = null;
                }
            }
            this._disposed = true;
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        /// <summary>  
        /// 保存数据DB文件到硬盘  
        /// </summary>  
        public void Save()
        {
            Redis.Save();
        }
        /// <summary>  
        /// 异步保存数据DB文件到硬盘  
        /// </summary>  
        public void SaveAsync()
        {
            Redis.SaveAsync();
        }
    }

    /// <summary>  
    /// HashOperator类，是操作哈希表类。继承自RedisOperatorBase类  
    /// </summary>  
    public class HashOperator : RedisOperatorBase
    {
        public HashOperator() : base() { }
        /// <summary>  
        /// 判断某个数据是否已经被缓存  
        /// </summary>  
        public bool Exist<T>(string hashId, string key)
        {
            return Redis.HashContainsEntry(hashId, key);
        }
        /// <summary>  
        /// 存储数据到hash表  
        /// </summary>  
        public bool Set<T>(string hashId, string key, T t)
        {
            var value = JsonSerializer.SerializeToString<T>(t);
            return Redis.SetEntryInHash(hashId, key, value);
        }
        /// <summary>  
        /// 移除hash中的某值  
        /// </summary>  
        public bool Remove(string hashId, string key)
        {
            return Redis.RemoveEntryFromHash(hashId, key);
        }
        /// <summary>  
        /// 移除整个hash  
        /// </summary>  
        public bool Remove(string key)
        {
            return Redis.Remove(key);
        }
        /// <summary>  
        /// 从hash表获取数据  
        /// </summary>  
        public T Get<T>(string hashId, string key)
        {
            string value = Redis.GetValueFromHash(hashId, key);
            return JsonSerializer.DeserializeFromString<T>(value);
        }
        /// <summary>  
        /// 获取整个hash的数据  
        /// </summary>  
        public List<T> GetAll<T>(string hashId)
        {
            var result = new List<T>();
            var list = Redis.GetHashValues(hashId);
            if (list != null && list.Count > 0)
            {
                list.ForEach(x =>
                {
                    var value = JsonSerializer.DeserializeFromString<T>(x);
                    result.Add(value);
                });
            }
            return result;
        }
        /// <summary>  
        /// 设置缓存过期  
        /// </summary>  
        public void SetExpire(string key, DateTime datetime)
        {
            Redis.ExpireEntryAt(key, datetime);
        }
    }
}
